<?php

namespace common\utils;

use Illuminate\Support\Facades\Log;


class CommonSDK
{
    /**
     * API地址
     * 
     * @var string
     */
    public $baseUrl;

    /**
     * 超时时间
     * 
     * @var int
     */
    public $timeout;

    /**
     * 请求返回对象
     * 
     * @var \Psr\Http\Message\ResponseInterface
     */
    public $resp;

    /**
     * 错误信息
     * 
     * @var array
     */
    public $errors = [];

    /**
     * @param string $baseUrl API地址
     * @param int    $timeout 超时时间
     */
    public function __construct($baseUrl = '', $timeout = 30)
    {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->timeout = $timeout;
    }

    /**
     * 获取错误信息
     * 
     * @return array
     */
    public function getErrors()
    {
        return $this->errors;
    }

    /**
     * 获取返回对象
     * 
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function getResponse()
    {
        return $this->resp;
    }

    /**
     * ***************************************************************************************************
     * ***********************************  partner server ***********************************************
     * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
     */
    /**
     * 手动处理转账异常单
     *
     * @param string $hallID       厅id
     * @param string $userID       用户id
     * @return false|array
     */
    public function handleTransfer($id, $status, $remark=null) {
        $params = [
            'money_transfer_id' => $id,
            'status' => $status,
            'remark' => $remark,
        ];
        return $this->exec('/money/handleTransfer', 'POST', $params, false);
    }



    /**
     * ***************************************************************************************************
     * ***********************************  common server ************************************************
     * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
     */
    /**
     * 查詢第三方额度转换订单状态
     * @param $partnerName
     * @param $partnerUsername
     * @param $orderNumber
     * @return \Psr\Http\Message\ResponseInterface|null
     */
    public function checkTransferResult($partnerName, $partnerUsername, $orderNumber, $beginTime=null, $checkTime=5){
        $beginTime = $beginTime ? $beginTime : time();
        $data = [
            'api_name' => $partnerName,
            'username' => $partnerUsername,
            'order_number' => $orderNumber,
            'begin_time' => $beginTime - $checkTime * 60,
            'end_time' => $beginTime + $checkTime * 60
        ];
        return $this->exec('/api/checkTransferResult', 'get', $data);
    }

    /**
     * 查询第三方转账 某时间点前后后5分钟记录
     * @param $partnerName
     * @param $partnerUsername
     * @param $beginTime
     * @return \Psr\Http\Message\ResponseInterface|null
     */
    public function getTransferResult($partnerName, $partnerUsername, $beginTime, $checkTime=5){
        $data = [
            'api_name' => $partnerName,
            'username' => $partnerUsername,
            'begin_time' => $beginTime - $checkTime * 60,
            'end_time' => $beginTime + $checkTime * 60
        ];
        return $this->exec('/api/getTransferResult', 'get', $data);
    }

    /**
     * 执行命令
     * 
     * @param string $url    请求地址
     * @param string $method 请求api的方法，get，post，patch 等
     * @param array  $data   数据，body数据，param 数据等
     * @param bool   $exit   出错了直接退出，某些API要处理后续逻辑，不能直接退出，如转账，支付等
     * 
     * @return null|\Psr\Http\Message\ResponseInterface
     */
    private function exec($url, $method, $data, $exit = false)
    {
        $url = $this->baseUrl . '/' . ltrim($url, '/');
        $resp = request($url, $method, $data, [], true, [], $this->timeout);
        $this->resp = $resp;
        $ret = json_decode($resp->getBody()->getContents(), true);
        
        // 统一处理错误
        if (!isset($ret["code"]) || $ret["code"] != SysCode::OK) {
            $this->errors = [
                'url' => $url,
                'method' => $method,
                'data' => $data,
                'status' => $resp->getStatusCode(),
                'ret' => $ret
            ];
            Log::error("Partner Server Request Error: ", $this->errors);
            if ($exit) {
                // 出错直接退出
                if (env('APP_DEBUG') == true) {
                    return error_exit(SysCode::INTERNAL_SERVER_ERROR, "Partner Server Error!", $this->errors);
                } else {
                    return error_exit(SysCode::INTERNAL_SERVER_ERROR);
                }
            } else {
                // curl报错：网络连接，超时等不可预知错误
                if ($resp->getStatusCode() < 100) {
                    return null;
                }
            }
        }
        return $ret;
    }
}